//
//  TaskPool.m
//  Pitch
//
//  Created by zhujinhui on 14-9-11.
//  Copyright (c) 2014年 zhujinhui. All rights reserved.
//

#import "TaskPool.h"

@interface TaskPool (){
    NSOperationQueue        *pool;
    NSMutableDictionary     *serviceTokenForController;
    NSMutableDictionary     *serviceTokenForDelegate;
    NSMutableArray          *services;
    
}

@end

@implementation TaskPool

static TaskPool *instance;

+(TaskPool *) shareInstance{
    if (!instance) {
        instance = [[TaskPool alloc]init];
        instance->pool = [[NSOperationQueue alloc]init];
        [instance->pool setMaxConcurrentOperationCount:4];
        
        instance->serviceTokenForController = [[NSMutableDictionary alloc]init];
        instance->serviceTokenForDelegate = [[NSMutableDictionary alloc]init];
        instance->services = [[NSMutableArray alloc]init];
        
    }
    return instance;
}


-(NSString *) doTaskWithService:(NSString *)serviceName{
    //cancel the task if the task is doing
    //    if (self.bindedController) {
    //        [services addObject:serviceName];
    //        self.bindedController.services = services;
    //    }
    if ([serviceTokenForController objectForKey:serviceName]) {
        [self cancelTask:serviceName];
    }else{
        NSLog(@"a new task started!");
    }
    if (self.bindedController) {
        //remeber the controllor who bind the service
        NSString *controllerString = NSStringFromClass([self.bindedController class]);
        [serviceTokenForController setObject:controllerString forKey:serviceName];
    }
    if (self.mDelegate){
        //remeber the delegate who delegate the service
        NSString *delegateString = NSStringFromClass([self.mDelegate class]);
        [serviceTokenForDelegate setObject:delegateString forKey:serviceName];
//        NSArray *allKeys = [serviceToken allKeys];
//        for (NSString *serviceNameItem in allKeys) {
//            if (![serviceNameItem isEqualToString:serviceName]) {
//                id<TaskPoolDelegate> delegate = self.mDelegate ;
//                [delegate mDelegate] = nil;
//            }
//        }
    }
    
    //add service to the operationqueue
    ServiceMediator *op = [[ServiceMediator alloc]initWithService:serviceName delegate:self];
    [pool addOperation:op];
    
    return serviceName;
}

#pragma mark - ServiceMediator Delegate
-(void)serviceMediator:(ServiceMediator *)service resultDidFetched:(NetworkResponse *) response{
    //remove current service
    
    if (self.bindedController) {
        
        NSString *oldControllerString = [serviceTokenForController objectForKey:service.serviceName];
        NSString *currentControllerString = NSStringFromClass([self.bindedController class]);
        if ([oldControllerString isEqualToString:currentControllerString]) {
            dispatch_async(dispatch_get_main_queue(), ^{
                // update ui and other action show execute on main thread
                [self.bindedController refreshDataWithService:service.serviceName andResponse:response];
            });
            
            
        }else{
            NSLog(@"kyson:Controller changed,old:%@,new:%@",oldControllerString,currentControllerString);
        }
    }else{
        NSLog(@"kyson:Controller not binded");
    }
    
    
    //call back
    if (self.mDelegate && [self.mDelegate respondsToSelector:@selector(taskPool:serviceWithNameDidFinished:response:)]) {
        NSString *oldDelegateString = [serviceTokenForDelegate objectForKey:service.serviceName];
        NSString *currentDelegateString = NSStringFromClass([self.mDelegate class]);
        if ([oldDelegateString isEqualToString:currentDelegateString]) {
            dispatch_async(dispatch_get_main_queue(), ^{
                // update ui and other action show execute on main thread
                [self.mDelegate taskPool:self serviceWithNameDidFinished:service.serviceName response:response];
            });
        }else{
            NSLog(@"kyson:Controller changed,old:%@,new:%@",oldDelegateString,currentDelegateString);
        }
        
    }else{
        NSLog(@"kyson:%@ delegate not setted",self);
    }
    
    [serviceTokenForDelegate removeObjectForKey:service.serviceName];
    
}



-(BOOL)cancelTask:(NSString*) serviceName{
    NSArray *ops = [pool operations];
    for (ServiceMediator *op in ops) {
        if ([op.serviceName isEqualToString:serviceName]) {
            [op cancel];
            return YES;
        }
    }
    return NO;
}


-(void)cancelcurrentTask{
    if (self.bindedController) {
        NSArray *controllerServices = self.bindedController.services;
        for (NSString *serviceName in controllerServices) {
            [self cancelTask:serviceName];
        }
    }
}


@end
